package com.ugoodtech.mdcc.core.service.impl;

import com.mysema.query.BooleanBuilder;
import com.ugoodtech.mdcc.core.Constants;
import com.ugoodtech.mdcc.core.domain.*;
import com.ugoodtech.mdcc.core.helper.SearchVoId;
import com.ugoodtech.mdcc.core.repository.*;
import com.ugoodtech.mdcc.core.service.SearchPermissionsService;
import com.ugoodtech.mdcc.core.service.VstarCustomerService;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class VstarCustomerServiceImpl implements VstarCustomerService {

    private static final Logger logger = LoggerFactory.getLogger(VstarCustomerServiceImpl.class);

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserProfileRepository userProfileRepository;

    @Autowired
    private CustomerRegularReportRepository customerRegularReportRepository;

    @Autowired
    private StationCustomerReportRepository stationCustomerReportRepository;

    @Autowired
    private QuestionAnswerOptionRepository questionAnswerOptionRepository;

    @Autowired
    private SearchPermissionsService searchPermissionsService;

    @Autowired
    private DepartmentRepository departmentRepository;
    @Autowired
    private StationRegularServiceReportRepository stationRegularServiceReportRepository;
    @Autowired
    private StationColorReportRepository stationColorReportRepository;
    @Autowired
    private StationReportRepository stationReportRepository;


    //筛选条件
    @Override
    public List<CustomerRegularReport> builder(String province, String brand, String category, String stationName,
                                               Long serviceStartTime, Long serviceEndTime, Long startTime, Long endTime, String serviceType,
                                               Integer serviceNum, Long userId, String userName, String department, String city, String customerStat,
                                               String customerType,String paintBrand,String productPosition,String reportStatus,String score,String isManaged,
                                               String serviceReportStatus,Boolean paintType,String payService,String sentTime,String serviceTime,String stationNum) {
        Long time = System.currentTimeMillis();

        String[] cities = null;
        String[] categories = null;
        Long[] customerStats = null;
        Long[] customerTypes = null;
        String[] paintBrands = null;
        String[] productPositions = null;
        String[] serviceTypes = null;
        String[] serviceReportStatuses = null;
        String[] reportStatuses = null;
        String[] departments = null;

        if (StringUtils.isNotEmpty(city)){
            cities = city.split(",");
        }
        if (StringUtils.isNotEmpty(category)){
            categories = category.split(",");
        }
        if (StringUtils.isNotEmpty(paintBrand)){
            paintBrands = paintBrand.split(",");
        }
        if (StringUtils.isNotEmpty(productPosition)){
            productPositions = productPosition.split(",");
        }
        if (StringUtils.isNotEmpty(serviceType)){
            serviceTypes = serviceType.split(",");
        }
        if (StringUtils.isNotEmpty(department)){
            departments = department.split(",");
        }
        if (StringUtils.isNotEmpty(serviceReportStatus)){
            serviceReportStatuses = serviceReportStatus.split(",");
        }
        if (StringUtils.isNotEmpty(reportStatus)){
            reportStatuses = reportStatus.split(",");
        }
        if (StringUtils.isNotEmpty(customerStat)){
            customerStats = (Long[]) ConvertUtils.convert(customerStat.split(","),Long.class);
        }
        if (StringUtils.isNotEmpty(customerType)){
            customerTypes = (Long[]) ConvertUtils.convert(customerType.split(","),Long.class);
        }

        User user = userRepository.findOne(userId);
        UserProfile userProfile = userProfileRepository.findByUserId(userId);
        SearchVoId searchVoId;
        if (user.getUserType().equals(UserType.dealers)) {
            searchVoId = searchPermissionsService.getDealersStationId(userProfile, province, brand);
        } else {
            searchVoId = searchPermissionsService.searchColorReportByProvinceBrand(userProfile, province, brand);
        }
        if (searchVoId.getResultStationId().isEmpty()) {
            return new ArrayList<>();
        }

        QCustomerRegularReport qCustomerRegularReport = QCustomerRegularReport.customerRegularReport;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qCustomerRegularReport.deleted.eq(false));
        builder.and(qCustomerRegularReport.enabled.eq(true));
        builder.and(qCustomerRegularReport.customerReport.isNotNull());
        builder.and(qCustomerRegularReport.customerReport.station.id.in(searchVoId.getResultStationId()));

        if (cities!=null) {
            builder.and(qCustomerRegularReport.customerReport.station.city.in(cities));
        }
        if (customerStats!=null) {
            builder.and(qCustomerRegularReport.customerReport.station.customerStat.in(customerStats));
        }
        if (customerTypes!=null) {
            builder.and(qCustomerRegularReport.customerReport.station.customerType.in(customerTypes));
        }
        if (paintBrands!=null) {
            BooleanBuilder builderOr = new BooleanBuilder();
            for (String str : paintBrands){
                builder.or(qCustomerRegularReport.customerReport.station.paintBrand.like("%" + str + "%"));
            }
            builder.and(builderOr);
        }
        if (productPositions!=null) {
            BooleanBuilder builderOr = new BooleanBuilder();
            for (String str : paintBrands){
                builder.or(qCustomerRegularReport.customerReport.station.productPosition.like("%" + str + "%"));
            }
            builder.and(builderOr);
        }
        if (categories!=null) {
            builder.and(qCustomerRegularReport.customerReport.station.category.in(categories));
        }
        if (StringUtils.isNotEmpty(stationName)) {
            builder.and(qCustomerRegularReport.customerReport.station.name.like("%" + stationName + "%"));
        }
        if (StringUtils.isNotEmpty(stationNum)) {
            builder.and(qCustomerRegularReport.customerReport.station.stationNum.like("%" + stationNum + "%"));
        }

        if (serviceStartTime != null && serviceStartTime != 0){
            builder.and(qCustomerRegularReport.regularReport.startServiceTime.after(new Date(serviceStartTime)));
        }if(serviceEndTime != null && serviceEndTime != 0) {
            builder.and(qCustomerRegularReport.regularReport.endServiceTime.before(new Date(serviceEndTime)));
        }
        if (startTime != null && startTime != 0){
            builder.and(qCustomerRegularReport.creationTime.after(new Date(startTime)));
        }
        if(endTime != null && endTime != 0) {
            builder.and(qCustomerRegularReport.creationTime.before(new Date(endTime)));
        }
        if (serviceTypes != null || serviceReportStatuses != null ) {
            //先从报告答案中找出所有填写过ids中任何一个id的答案
            QStationRegularServiceReport qStationRegularServiceReport = QStationRegularServiceReport.stationRegularServiceReport;
            BooleanBuilder regularBuilder = new BooleanBuilder();
            regularBuilder.and(qStationRegularServiceReport.deleted.eq(false));
            regularBuilder.and(qStationRegularServiceReport.enabled.eq(true));
            BooleanBuilder builderOr = new BooleanBuilder();
            if (serviceTypes != null) {
                for (String id : serviceTypes) {
                    builderOr.or(qStationRegularServiceReport.answerId.like("%" + id + "%"));
                }
                regularBuilder.and(builderOr);
            }
            if (serviceReportStatuses != null){
                for (String id : serviceReportStatuses) {
                    builderOr.or(qStationRegularServiceReport.answerId.like("%" + id + "%"));
                }
                regularBuilder.and(builderOr);
            }
            List<StationRegularServiceReport> list = (List<StationRegularServiceReport>) stationRegularServiceReportRepository.findAll(regularBuilder);
            if (list == null || list.size()==0){
                return new ArrayList<>();
            }else {
                List<Long> stationsIDs = new ArrayList<>();
                for (StationRegularServiceReport report : list){
                    stationsIDs.add(report.getStationReport().getStation().getId());
                }
                builder.and(qCustomerRegularReport.regularReport.station.id.in(stationsIDs));
            }
        }
        if (serviceNum != null) {
            builder.and(qCustomerRegularReport.regularReport.station.user.serviceNum.eq(serviceNum));
        }
        if (reportStatuses!=null){
            QStationReport qStationReport = QStationReport.stationReport;
            BooleanBuilder colorBuilder = new BooleanBuilder();
            colorBuilder.and(qStationReport.deleted.eq(false));
            colorBuilder.and(qStationReport.enabled.eq(true));
            BooleanBuilder builderOr = new BooleanBuilder();
            for (String str:reportStatuses){
                builderOr.or(qStationReport.exceptionType.in(str));
            }
            colorBuilder.and(builderOr);
            List<StationReport> list = (List<StationReport>) stationReportRepository.findAll(colorBuilder);
            if (list == null || list.size()==0){
                return new ArrayList<>();
            }else {
                List<Long> stationsIDs = new ArrayList<>();
                for (StationReport report : list){
                    stationsIDs.add(report.getStation().getId());
                }
                builder.and(qCustomerRegularReport.regularReport.station.id.in(stationsIDs));
            }
        }
        if (StringUtils.isNotEmpty(userName) || departments != null) {
            QStationColorReport qStationColorReport = QStationColorReport.stationColorReport;
            QUserProfile qUserProfile = QUserProfile.userProfile;
            BooleanBuilder booleanBuilder = new BooleanBuilder();
            booleanBuilder.and(qUserProfile.deleted.eq(false));
            booleanBuilder.and(qUserProfile.enabled.eq(true));
            booleanBuilder.and(qUserProfile.user.userFlag.in(0,2));
            boolean flag = false;
            if (StringUtils.isNotEmpty(userName)) {
                flag = true;
                booleanBuilder.and(qUserProfile.realName.like("%" + userName + "%"));
            }
            if (departments != null){
                flag = true;
                booleanBuilder.and(qUserProfile.user.userFlag.in(0,2));
                booleanBuilder.and(qUserProfile.user.userType.in(UserType.admin,UserType.dealers,UserType.insiders));
                for (String str:departments){
                    booleanBuilder.or(qUserProfile.departmentList.any().name.eq(str));
                }
            }
            if (flag) {
                List<UserProfile> userProfileList = (List<UserProfile>) userProfileRepository.findAll(booleanBuilder);
                if (userProfileList == null || userProfileList.size() == 0) {
                    return new ArrayList<>();
                }
                List<Long> userIds = new ArrayList<>();
                for (UserProfile userp : userProfileList) {
                    userIds.add(userp.getUser().getId());
                }
                BooleanBuilder colorBuilder = new BooleanBuilder();
                colorBuilder.and(qStationColorReport.deleted.eq(false));
                colorBuilder.and(qStationColorReport.enabled.eq(true));
                colorBuilder.and(qStationColorReport.stationReport.station.report_finished.in(1, 2, 3));
                colorBuilder.and(qStationColorReport.stationReport.user.id.in(userIds));
                List<StationColorReport> list = (List<StationColorReport>) stationColorReportRepository.findAll(colorBuilder);
                if (list == null || list.size() == 0) {
                    return new ArrayList<>();
                }
                List<Long> ids = new ArrayList<>();
                for (StationColorReport report : list) {
                    if (report.getReportId() != null) {
                        ids.add(Long.parseLong(report.getReportId()));
                    }
                }
                builder.and(qCustomerRegularReport.regularReport.id.in(ids));
            }
        }
        if (paintType != null){
            builder.and(qCustomerRegularReport.regularReport.station.isPaint.eq(paintType?1:0));
        }
        if (payService != null || sentTime!=null || serviceTime!=null){
            QStationColorReport qStationColorReport = QStationColorReport.stationColorReport;
            BooleanBuilder builderStationColor = new BooleanBuilder();
            builderStationColor.and(qStationColorReport.deleted.eq(false));
            builderStationColor.and(qStationColorReport.enabled.eq(true));
            boolean flag = false;
            if (payService!=null){
                flag = true;
                builderStationColor.and(qStationColorReport.answerId.like("%"+payService+"%"));
            }
            if (sentTime!=null){
                flag = true;
                builderStationColor.and(qStationColorReport.answerId.like("%"+sentTime+"%"));
            }
            if (serviceTime!=null){
                flag = true;
                builderStationColor.and(qStationColorReport.answerId.like("%"+serviceTime+"%"));
            }
            if (flag) {
                List<StationColorReport> stationColorReports = (List<StationColorReport>) stationColorReportRepository.findAll(builderStationColor);
                if (stationColorReports == null || stationColorReports.size() == 0) {
                    return new ArrayList<>();
                }
                List<Long> Ids = new ArrayList<>();
                for (StationColorReport report : stationColorReports) {
                    Ids.add(report.getStationReport().getStation().getId());
                }
                builder.and(qCustomerRegularReport.regularReport.station.id.in(Ids));
            }
        }

        String[] str = new String[61];
        for (int i = 0; i < str.length; i++) {
            str[i] = i + "";
        }
        String[] notStr = new String[39];
        int index = 61;
        for (int i = 0; i < 39; i++) {
            notStr[i] = index + "";
            index += 1;
        }
        if (StringUtils.isNotEmpty(score)) {
            if (score.equals(Constants.FULL_MARKS)) {
                builder.and(qCustomerRegularReport.score.eq("100"));
            }
            if (score.equals(Constants.MORE_THAN_SIXTY)) {
                builder.and(qCustomerRegularReport.score.in(notStr));
            }
            if (score.equals(Constants.BELOW_THAN_SIXTY)) {
                builder.and(qCustomerRegularReport.score.in(str));
            }
        }
        if (StringUtils.isNotEmpty(isManaged)) {
            if (isManaged.equals(Constants.TRUE)) {
                builder.and(qCustomerRegularReport.managed.eq(true));
            }
            if (isManaged.equals(Constants.FALSE)) {
                builder.and(qCustomerRegularReport.managed.eq(false));
                builder.and(qCustomerRegularReport.score.in(str));
            }
        }
        List<CustomerRegularReport> customerRegularReportList = (List<CustomerRegularReport>) customerRegularReportRepository.findAll(builder);
        for (CustomerRegularReport report : customerRegularReportList) {
            if (StringUtils.isNotEmpty(score) && score.equals(Constants.BELOW_THAN_SIXTY)) {
                QStationCustomerReport qStationCustomerReport = QStationCustomerReport.stationCustomerReport;
                builder = new BooleanBuilder();
                builder.and(qStationCustomerReport.deleted.eq(false));
                builder.and(qStationCustomerReport.enabled.eq(true));
                builder.and(qStationCustomerReport.stationReport.id.eq(report.getCustomerReport().getId()));
                List<StationCustomerReport> customerReportList = (List<StationCustomerReport>) stationCustomerReportRepository.findAll();
                for (StationCustomerReport r : customerReportList) {
                    QuestionAnswerOption answerOption = questionAnswerOptionRepository.findOne(Long.valueOf(r.getAnswerId()));
                    if (answerOption.getName().equals("80%") || answerOption.getName().equals("100%")) {
                        continue;
                    }
                }
            }
            customerRegularReportList.add(report);
        }
        logger.info("最终查出的报告有：" + customerRegularReportList.size() + "份");
        logger.info("筛选报告用时：{}", System.currentTimeMillis() - time);
        return customerRegularReportList;
    }

    //筛选条件
    @Override
    public List<CustomerRegularReport> builder(String provinces, String brand, String category, Long stationId,
                                               Long serviceStartTime, Long serviceEndTime, Long startTime, Long endTime, Long serviceType,
                                               Integer serviceNum, Long userId, Boolean iFillin, String scoreType, String followType, Long loginUserId, Long departmentId) {
        Long time = System.currentTimeMillis();
        QCustomerRegularReport qCustomerRegularReport = QCustomerRegularReport.customerRegularReport;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qCustomerRegularReport.deleted.eq(false));
        builder.and(qCustomerRegularReport.enabled.eq(true));
        builder.and(qCustomerRegularReport.customerReport.isNotNull());

        User user = userRepository.findOne(loginUserId);
        UserProfile userProfile = userProfileRepository.findByUserId(loginUserId);
        SearchVoId searchVoId;
        if (user.getUserType().equals(UserType.dealers)) {
            searchVoId = searchPermissionsService.getDealersStationId(userProfile, provinces, brand);
        } else {
            searchVoId = searchPermissionsService.searchColorReportByProvinceBrand(userProfile, provinces, brand);
        }
        if (searchVoId.getResultStationId().isEmpty()) {
            return new ArrayList<>();
        }
        if (null != departmentId) {
            List<Long> searchDepartmentIds = new ArrayList<>();
            List<Department> departmentList = departmentRepository.getParentDeprtments();
            List<Long> departmentIdList = new ArrayList<>();
            for (Department department : departmentList) {
                departmentIdList.add(department.getId());
            }
            if (departmentIdList.contains(departmentId)) {
                departmentList = departmentRepository.selectParentDeparmentL(departmentId);
                for (Department department : departmentList) {
                    searchDepartmentIds.add(department.getId());
                }
            } else {
                searchDepartmentIds.add(departmentId);
            }
            QUserProfile qUserProfile = QUserProfile.userProfile;
            BooleanBuilder userBuilder = new BooleanBuilder();
            userBuilder.and(qUserProfile.deleted.eq(false));
            userBuilder.and(qUserProfile.enabled.eq(true));
            userBuilder.and(qUserProfile.departmentList.any().id.in(searchDepartmentIds));
            List<UserProfile> userProfileList = (List<UserProfile>) userProfileRepository.findAll(userBuilder);
            List<Long> userIdList = new ArrayList<>();
            for (UserProfile profile : userProfileList) {
                if (null != profile) {
                    userIdList.add(profile.getUser().getId());
                }
            }
            if (!userIdList.isEmpty()) {
                builder.and(qCustomerRegularReport.regularReport.user.id.in(userIdList));
            }
        }
        builder.and(qCustomerRegularReport.regularReport.station.id.in(searchVoId.getResultStationId()));
        if (StringUtils.isNotEmpty(category)) {
            builder.and(qCustomerRegularReport.regularReport.station.category.eq(category));
        }
        if (stationId != null && stationId != 0) {
            builder.and(qCustomerRegularReport.regularReport.station.id.eq(stationId));
        }
        if (serviceStartTime != null && serviceStartTime != 0 && serviceEndTime != null && serviceEndTime != 0) {
            builder.and(qCustomerRegularReport.regularReport.startServiceTime.after(new Date(serviceStartTime)));
            builder.and(qCustomerRegularReport.regularReport.endServiceTime.before(new Date(serviceEndTime)));
        }
        if (startTime != null && startTime != 0 && endTime != null && endTime != 0) {
            builder.and(qCustomerRegularReport.creationTime.after(new Date(startTime)));
            builder.and(qCustomerRegularReport.creationTime.before(new Date(endTime)));
        }
        if (serviceType != null && serviceType != 0) {
            builder.and(qCustomerRegularReport.regularReport.serviceTypAnswerIds.like("%" + serviceType + "%"));
        }
        if (serviceNum != null && serviceNum != 0) {
            builder.and(qCustomerRegularReport.regularReport.user.serviceNum.eq(serviceNum));
        }
        if (iFillin != null) {
            if (iFillin.equals(false)) {
                builder.and(qCustomerRegularReport.type.eq(false));
            } else {
                builder.and(qCustomerRegularReport.type.eq(true));
            }
        }
        String[] str = new String[61];
        for (int i = 0; i < str.length; i++) {
            str[i] = i + "";
        }
        String[] notStr = new String[39];
        int index = 61;
        for (int i = 0; i < 39; i++) {
            notStr[i] = index + "";
            index += 1;
        }
        if (StringUtils.isNotEmpty(scoreType)) {
            if (scoreType.equals(Constants.FULL_MARKS)) {
                builder.and(qCustomerRegularReport.score.eq("100"));
            }
            if (scoreType.equals(Constants.MORE_THAN_SIXTY)) {
                builder.and(qCustomerRegularReport.score.in(notStr));
            }
            if (scoreType.equals(Constants.BELOW_THAN_SIXTY)) {
                builder.and(qCustomerRegularReport.score.in(str));
            }
        }

        if (userId != null && userId != 0) {
            builder.and(qCustomerRegularReport.regularReport.user.id.eq(userId));
        }


        List<CustomerRegularReport> customerRegularReportList = (List<CustomerRegularReport>) customerRegularReportRepository.findAll(builder);
        List<CustomerRegularReport> reportList = new ArrayList<>();
        for (CustomerRegularReport report : customerRegularReportList) {
            if (StringUtils.isNotEmpty(scoreType) && scoreType.equals(Constants.BELOW_THAN_SIXTY)) {
                QStationCustomerReport qStationCustomerReport = QStationCustomerReport.stationCustomerReport;
                builder = new BooleanBuilder();
                builder.and(qStationCustomerReport.deleted.eq(false));
                builder.and(qStationCustomerReport.enabled.eq(true));
                builder.and(qStationCustomerReport.stationReport.id.eq(report.getCustomerReport().getId()));
                List<StationCustomerReport> customerReportList = (List<StationCustomerReport>) stationCustomerReportRepository.findAll();
                for (StationCustomerReport r : customerReportList) {
                    QuestionAnswerOption answerOption = questionAnswerOptionRepository.findOne(Long.valueOf(r.getAnswerId()));
                    if (answerOption.getName().equals("80%") || answerOption.getName().equals("100%")) {
                        continue;
                    }
                }
            }
            reportList.add(report);
        }
        logger.info("最终查出的报告有：" + customerRegularReportList.size() + "份");
        logger.info("筛选报告用时：{}", System.currentTimeMillis() - time);
        return customerRegularReportList;
    }

}
